<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>incremental md5</title>
    <style>
        body {
            text-align: center;
            font: 13px Tahoma
        }

        form {
            margin: 9vh auto
        }

        pre {
            background: #ffd;
            border: 1px solid orange;
            padding: 1em;
            margin: 0 auto;
            display: none;
            text-align: left;
            line-height: 1.25
        }
    </style>
</head>
<body>
<h1>incremental md5 demo</h1>
<form method="POST" enctype="multipart/form-data" onsubmit="return false;">
    <input id=file type=file placeholder="select a file"/>
</form>
<button id="fileButton">File</button>
<div id="dropTarget">dropTarget</div>
<pre id=log></pre>
<script src="/plugins/md5/spark-md5.min.js"></script>
<script src="/plugins/uploader/uploader.min.js"></script>
<script>
    let uploader = new Uploader({
        target: '/api/upload',
        chunkSize: 1024 * 1024 * 2,
        simultaneousUploads: 1,
        singleFile: true,
        testChunks: true,
        checkChunkUploadedByResponse: function (chunk, message) {
            let objMessage = {}
            try {
                objMessage = JSON.parse(message)
                console.log("process:" + chunk + ": " + objMessage);
            } catch (e) {
            }
            return (objMessage.uploaded_chunks || []).indexOf(chunk.offset + 1) >= 0
        }
    });
    uploader.assignBrowse(document.getElementById('fileButton'))
    uploader.assignDrop(document.getElementById('dropTarget'))
    uploader.on('fileAdded', function (file, event) {
        console.log(file, event)
        calculateFileMd5AndUpload(file.file)
    })
    uploader.on('fileSuccess', function (rootFile, file, message) {
        console.log("fileSuccess:" + message);
        console.log(rootFile, file, message)
    })
    uploader.on('fileComplete', function (rootFile) {
        console.log("fileComplete ");
        console.log(rootFile)
    })
    uploader.on('fileError', function (rootFile, file, message) {
        console.log("fileComplete:" + message);
        console.log(rootFile, file, message)
    })

    function calculateFileMd5AndUpload(file) {
        let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
        let chunkSize = 1024 * 1024 * 2;
        let chunks = Math.ceil(file.size / chunkSize);
        let currentChunk = 0;
        let spark = new SparkMD5.ArrayBuffer();
        let fileReaderOnload = function (e) {
            spark.append(e.target.result);
            currentChunk++;
            if (currentChunk < chunks) {
                loadNext();
            } else {
                console.log("computed hash:\n" + spark.end());
                uploader.upload();
            }
        }
        let fileReaderOnerror = function () {
            console.log(" oops, something went wrong.");
        };

        function loadNext() {
            let fileReader = new FileReader();
            fileReader.onload = fileReaderOnload;
            fileReader.onerror = fileReaderOnerror;
            let start = currentChunk * chunkSize;
            let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
            fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
        }

        loadNext();
    }
</script>
</body>
</html>